package com.gitee.wsl.android.ui.ext.type

import android.content.res.ColorStateList
import android.graphics.drawable.Drawable
import android.graphics.drawable.GradientDrawable
import android.graphics.drawable.RippleDrawable
import android.graphics.drawable.StateListDrawable
import android.os.Build
import com.gitee.wsl.common.ui.ext.shape.builder.AbstractShapeBuilder
import com.gitee.wsl.common.ui.ext.shape.builder.ShapeType
import com.gitee.wsl.ext.base.StateElement

fun sampleStateListDrawable(builder: SelectorBuilder.() -> Unit): StateListDrawable {
    val stateListBuilder = SelectorBuilder()
    stateListBuilder.builder()
    return stateListBuilder.build()
}

fun sampleShapeDrawable(shapeType: ShapeType = ShapeType.RECTANGLE, builder: ShapeBuilder.() -> Unit): GradientDrawable {
    val shapeBuilder = ShapeBuilder(shapeType)
    shapeBuilder.builder()

    return shapeBuilder.build()
}

fun sampleRippleDrawable(builder: RippleBuilder.() -> Unit): RippleDrawable {
    val rippleBuilder = RippleBuilder()
    rippleBuilder.builder()
    return rippleBuilder.build()
}

class ShapeBuilder(shapeType: ShapeType): AbstractShapeBuilder(shapeType){

    var solid: ColorStateList? = null
    var orientation = GradientDrawable.Orientation.TOP_BOTTOM

}


fun ShapeBuilder.solid(color: Int): ShapeBuilder {
    this.solid = ColorStateList.valueOf(color)
    return this
}

fun ShapeBuilder.build(): GradientDrawable {
    val gradientDrawable = GradientDrawable()

    gradientDrawable.orientation = orientation
    val colors = gradientBuilder.colors
    if (colors.size < 2) {
        gradientDrawable.color = solid
    } else {
        gradientDrawable.colors = colors
    }
    gradientDrawable.shape = shapeType.ordinal
    gradientDrawable.useLevel = gradientBuilder.useLevel
    gradientDrawable.gradientType = gradientBuilder.type.ordinal
    gradientDrawable.gradientRadius = gradientBuilder.radius
    gradientDrawable.setGradientCenter(gradientBuilder.centerX, gradientBuilder.centerY)

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
        gradientDrawable.setPadding(
            paddingBuilder.left,
            paddingBuilder.top,
            paddingBuilder.right,
            paddingBuilder.bottom
        )
    }

    gradientDrawable.setStroke(
        strokeBuilder.width,
        strokeBuilder.color,
        strokeBuilder.dashWidth,
        strokeBuilder.dashGap
    )

    gradientDrawable.cornerRadii = floatArrayOf(
        cornersBuilder.topLeft,
        cornersBuilder.topLeft,
        cornersBuilder.topRight,
        cornersBuilder.topRight,
        cornersBuilder.bottomLeft,
        cornersBuilder.bottomLeft,
        cornersBuilder.bottomRight,
        cornersBuilder.bottomRight,
    )

    return gradientDrawable
}

class SelectorBuilder {

    private var default: Drawable? = null
    private var defaultBuilder: (() -> Drawable)? = null
    private var builders = mutableListOf<StateBuilder>()

    fun defState(drawable: Drawable): SelectorBuilder {
        this.default = drawable
        return this
    }

    fun defState(builder: () -> Drawable): SelectorBuilder {
        defaultBuilder = builder
        return this
    }

    fun addState(state: StateElement, drawable: Drawable): SelectorBuilder {
        val stateBuilder = StateBuilder(state)
        stateBuilder.drawable(drawable)
        builders.add(stateBuilder)
        return this
    }

    fun addState(state: StateElement, builder: () -> Drawable): SelectorBuilder {
        val stateBuilder = StateBuilder(state)
        stateBuilder.drawable(builder)
        builders.add(stateBuilder)
        return this
    }

    fun build(): StateListDrawable {
        val stateListDrawable = StateListDrawable()
        for (builder in builders) {
            stateListDrawable.addState(
                builder.stateElement.states,
                builder.drawable ?: builder.drawableBuilder?.invoke()
            )
        }
        val defaultDrawable = default ?: defaultBuilder?.invoke()
        if (defaultDrawable != null) {
            stateListDrawable.addState(intArrayOf(), defaultDrawable)
        }
        return stateListDrawable
    }

    class StateBuilder(val stateElement: StateElement) {
        var drawable: Drawable? = null
        var drawableBuilder: (() -> Drawable)? = null

        fun drawable(builder: () -> Drawable): StateBuilder {
            this.drawableBuilder = builder
            return this
        }

        fun drawable(drawable: Drawable): StateBuilder {
            this.drawable = drawable
            return this
        }

    }
}
class RippleBuilder {

    var color: ColorStateList? = null

    var content: Drawable? = null
    var contentBuilder: (() -> Drawable)? = null

    var mask: Drawable? = null
    var maskBuilder: (() -> Drawable)? = null

    fun color(color: Int): RippleBuilder {
        this.color = ColorStateList.valueOf(color)
        return this
    }

    fun content(builder: () -> Drawable): RippleBuilder {
        contentBuilder = builder
        return this
    }

    fun mask(builder: () -> Drawable): RippleBuilder {
        maskBuilder = builder
        return this
    }

    fun build(): RippleDrawable = RippleDrawable(
        color ?: throw NullPointerException(),
        content ?: contentBuilder?.invoke(),
        mask ?: maskBuilder?.invoke()
    )

}
